module point_mod

implicit none

type PointObj
    real :: x !< x coordinate of the point
    real :: y !< y coordinate of the point
    real :: z !< z coordinate of the point
end type

interface Point
    module procedure Point_Create_3D
end interface

!> Overload subtraction to give the
!interface Operator(-)
!    module procedure Point_Distance
!end interface

interface Assignment(=)
    module procedure Point_Copy
end interface

contains

!> Create a 3D point from x,y,z coordinate
pure type(PointObj) function Point_Create_3D(x, y, z) result(pt)
    real, intent(in) :: x
    real, intent(in) :: y
    real, intent(in) :: z
    pt%x = x
    pt%y = y
    pt%z = z
end function Point_Create_3D

!> Copy info between points
subroutine Point_Copy(pt_out, pt_in)
    type(PointObj), intent(out) :: pt_out !< point to copy to
    type(PointObj), intent(in)  :: pt_in  !< point to copy from
    pt_out%x = pt_in%x
    pt_out%y = pt_in%y
    pt_out%z = pt_in%z
end subroutine Point_Copy

!> Compute the distance between two points
 real function Point_Distance(pt1, pt2) result(d)
    type(PointObj), intent(in) :: pt1 !< first point
    type(PointObj), intent(in) :: pt2 !< second point
    d =     (pt2%x-pt1%x)*(pt2%x-pt1%x)
    d = d + (pt2%y-pt1%y)*(pt2%y-pt1%y)
    d = d + (pt2%z-pt1%z)*(pt2%z-pt1%z)
    d = sqrt(d)
end function Point_Distance


end module point_mod
